//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension WorkSpacesThinClient {
    // MARK: Enums

    public enum ApplyTimeOf: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case device = "DEVICE"
        case utc = "UTC"
        public var description: String { return self.rawValue }
    }

    public enum DayOfWeek: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case friday = "FRIDAY"
        case monday = "MONDAY"
        case saturday = "SATURDAY"
        case sunday = "SUNDAY"
        case thursday = "THURSDAY"
        case tuesday = "TUESDAY"
        case wednesday = "WEDNESDAY"
        public var description: String { return self.rawValue }
    }

    public enum DesktopType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case appstream = "appstream"
        case workspaces = "workspaces"
        case workspacesWeb = "workspaces-web"
        public var description: String { return self.rawValue }
    }

    public enum DeviceSoftwareSetComplianceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case compliant = "COMPLIANT"
        case none = "NONE"
        case notCompliant = "NOT_COMPLIANT"
        public var description: String { return self.rawValue }
    }

    public enum DeviceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case archived = "ARCHIVED"
        case deregistered = "DEREGISTERED"
        case deregistering = "DEREGISTERING"
        case registered = "REGISTERED"
        public var description: String { return self.rawValue }
    }

    public enum EnvironmentSoftwareSetComplianceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case compliant = "COMPLIANT"
        case noRegisteredDevices = "NO_REGISTERED_DEVICES"
        case notCompliant = "NOT_COMPLIANT"
        public var description: String { return self.rawValue }
    }

    public enum MaintenanceWindowType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case custom = "CUSTOM"
        case system = "SYSTEM"
        public var description: String { return self.rawValue }
    }

    public enum SoftwareSetUpdateMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case useDesired = "USE_DESIRED"
        case useLatest = "USE_LATEST"
        public var description: String { return self.rawValue }
    }

    public enum SoftwareSetUpdateSchedule: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case applyImmediately = "APPLY_IMMEDIATELY"
        case useMaintenanceWindow = "USE_MAINTENANCE_WINDOW"
        public var description: String { return self.rawValue }
    }

    public enum SoftwareSetUpdateStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case available = "AVAILABLE"
        case inProgress = "IN_PROGRESS"
        case upToDate = "UP_TO_DATE"
        public var description: String { return self.rawValue }
    }

    public enum SoftwareSetValidationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case notValidated = "NOT_VALIDATED"
        case validated = "VALIDATED"
        public var description: String { return self.rawValue }
    }

    public enum TargetDeviceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case archived = "ARCHIVED"
        case deregistered = "DEREGISTERED"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "cannotParse"
        case fieldValidationFailed = "fieldValidationFailed"
        case other = "other"
        case unknownOperation = "unknownOperation"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ConflictException: AWSErrorShape {
        public let message: String?
        /// The ID of the resource associated with the request.
        public let resourceId: String?
        /// The type of the resource associated with the request.
        public let resourceType: String?

        @inlinable
        public init(message: String? = nil, resourceId: String? = nil, resourceType: String? = nil) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct CreateEnvironmentRequest: AWSEncodableShape {
        /// Specifies a unique, case-sensitive identifier that you provide to ensure the idempotency of the request. This lets you safely retry the request without accidentally performing the same operation a second time. Passing the same value to a later call to an operation requires that you also pass the same value for all other parameters. We recommend that you use a UUID type of value. If you don't provide this value, then Amazon Web Services generates a random one for you. If you retry the operation with the same ClientToken, but with different parameters, the retry fails with an IdempotentParameterMismatch error.
        public let clientToken: String?
        /// The ID of the software set to apply.
        public let desiredSoftwareSetId: String?
        /// The Amazon Resource Name (ARN) of the desktop to stream from Amazon WorkSpaces, WorkSpaces Secure Browser, or AppStream 2.0.
        public let desktopArn: String
        /// The URL for the identity provider login (only for environments that use AppStream 2.0).
        public let desktopEndpoint: String?
        /// A map of the key-value pairs of the tag or tags to assign to the newly created devices for this environment.
        public let deviceCreationTags: [String: String]?
        /// The Amazon Resource Name (ARN) of the Key Management Service key to use to encrypt the environment.
        public let kmsKeyArn: String?
        /// A specification for a time window to apply software updates.
        public let maintenanceWindow: MaintenanceWindow?
        /// The name for the environment.
        public let name: String?
        /// An option to define which software updates to apply.
        public let softwareSetUpdateMode: SoftwareSetUpdateMode?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?
        /// A map of the key-value pairs of the tag or tags to assign to the resource.
        public let tags: [String: String]?

        @inlinable
        public init(clientToken: String? = CreateEnvironmentRequest.idempotencyToken(), desiredSoftwareSetId: String? = nil, desktopArn: String, desktopEndpoint: String? = nil, deviceCreationTags: [String: String]? = nil, kmsKeyArn: String? = nil, maintenanceWindow: MaintenanceWindow? = nil, name: String? = nil, softwareSetUpdateMode: SoftwareSetUpdateMode? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.desktopArn = desktopArn
            self.desktopEndpoint = desktopEndpoint
            self.deviceCreationTags = deviceCreationTags
            self.kmsKeyArn = kmsKeyArn
            self.maintenanceWindow = maintenanceWindow
            self.name = name
            self.softwareSetUpdateMode = softwareSetUpdateMode
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 512)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.desiredSoftwareSetId, name: "desiredSoftwareSetId", parent: name, pattern: "^[0-9]{1,9}$")
            try self.validate(self.desktopArn, name: "desktopArn", parent: name, max: 2048)
            try self.validate(self.desktopArn, name: "desktopArn", parent: name, min: 20)
            try self.validate(self.desktopArn, name: "desktopArn", parent: name, pattern: "^arn:[\\w+=\\/,.@-]+:[a-zA-Z0-9\\-]+:[a-zA-Z0-9\\-]*:[0-9]{0,12}:[a-zA-Z0-9\\-\\/\\._]+$")
            try self.validate(self.desktopEndpoint, name: "desktopEndpoint", parent: name, max: 1024)
            try self.validate(self.desktopEndpoint, name: "desktopEndpoint", parent: name, min: 1)
            try self.validate(self.desktopEndpoint, name: "desktopEndpoint", parent: name, pattern: "^(https:\\/\\/)[a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,32}(:[0-9]{1,5})?(\\/.*)?$")
            try self.deviceCreationTags?.forEach {
                try validate($0.key, name: "deviceCreationTags.key", parent: name, max: 128)
                try validate($0.key, name: "deviceCreationTags.key", parent: name, min: 1)
                try validate($0.key, name: "deviceCreationTags.key", parent: name, pattern: "^(?!aws:)[A-Za-z0-9 _=@:.+-/]+$")
                try validate($0.value, name: "deviceCreationTags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "deviceCreationTags[\"\($0.key)\"]", parent: name, pattern: "^[A-Za-z0-9 _=@:.+-/]+$")
            }
            try self.validate(self.deviceCreationTags, name: "deviceCreationTags", parent: name, max: 50)
            try self.validate(self.kmsKeyArn, name: "kmsKeyArn", parent: name, max: 2048)
            try self.validate(self.kmsKeyArn, name: "kmsKeyArn", parent: name, min: 20)
            try self.validate(self.kmsKeyArn, name: "kmsKeyArn", parent: name, pattern: "^arn:[\\w+=\\/,.@-]+:kms:[a-zA-Z0-9\\-]*:[0-9]{0,12}:key\\/[a-zA-Z0-9-]+$")
            try self.maintenanceWindow?.validate(name: "\(name).maintenanceWindow")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^$|^[0-9\\p{IsAlphabetic}+:,.@'\" -][0-9\\p{IsAlphabetic}+=:,.@'\" -]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case desktopArn = "desktopArn"
            case desktopEndpoint = "desktopEndpoint"
            case deviceCreationTags = "deviceCreationTags"
            case kmsKeyArn = "kmsKeyArn"
            case maintenanceWindow = "maintenanceWindow"
            case name = "name"
            case softwareSetUpdateMode = "softwareSetUpdateMode"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
            case tags = "tags"
        }
    }

    public struct CreateEnvironmentResponse: AWSDecodableShape {
        /// Describes an environment.
        public let environment: EnvironmentSummary?

        @inlinable
        public init(environment: EnvironmentSummary? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "environment"
        }
    }

    public struct DeleteDeviceRequest: AWSEncodableShape {
        /// Specifies a unique, case-sensitive identifier that you provide to ensure the idempotency of the request. This lets you safely retry the request without accidentally performing the same operation a second time. Passing the same value to a later call to an operation requires that you also pass the same value for all other parameters. We recommend that you use a UUID type of value. If you don't provide this value, then Amazon Web Services generates a random one for you. If you retry the operation with the same ClientToken, but with different parameters, the retry fails with an IdempotentParameterMismatch error.
        public let clientToken: String?
        /// The ID of the device to delete.
        public let id: String

        @inlinable
        public init(clientToken: String? = DeleteDeviceRequest.idempotencyToken(), id: String) {
            self.clientToken = clientToken
            self.id = id
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.clientToken, key: "clientToken")
            request.encodePath(self.id, key: "id")
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 512)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-zA-Z0-9]{24}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteDeviceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteEnvironmentRequest: AWSEncodableShape {
        /// Specifies a unique, case-sensitive identifier that you provide to ensure the idempotency of the request. This lets you safely retry the request without accidentally performing the same operation a second time. Passing the same value to a later call to an operation requires that you also pass the same value for all other parameters. We recommend that you use a UUID type of value. If you don't provide this value, then Amazon Web Services generates a random one for you. If you retry the operation with the same ClientToken, but with different parameters, the retry fails with an IdempotentParameterMismatch error.
        public let clientToken: String?
        /// The ID of the environment to delete.
        public let id: String

        @inlinable
        public init(clientToken: String? = DeleteEnvironmentRequest.idempotencyToken(), id: String) {
            self.clientToken = clientToken
            self.id = id
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.clientToken, key: "clientToken")
            request.encodePath(self.id, key: "id")
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 512)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-z0-9]{9}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteEnvironmentResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeregisterDeviceRequest: AWSEncodableShape {
        /// Specifies a unique, case-sensitive identifier that you provide to ensure the idempotency of the request. This lets you safely retry the request without accidentally performing the same operation a second time. Passing the same value to a later call to an operation requires that you also pass the same value for all other parameters. We recommend that you use a UUID type of value. If you don't provide this value, then Amazon Web Services generates a random one for you. If you retry the operation with the same ClientToken, but with different parameters, the retry fails with an IdempotentParameterMismatch error.
        public let clientToken: String?
        /// The ID of the device to deregister.
        public let id: String
        /// The desired new status for the device.
        public let targetDeviceStatus: TargetDeviceStatus?

        @inlinable
        public init(clientToken: String? = DeregisterDeviceRequest.idempotencyToken(), id: String, targetDeviceStatus: TargetDeviceStatus? = nil) {
            self.clientToken = clientToken
            self.id = id
            self.targetDeviceStatus = targetDeviceStatus
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodePath(self.id, key: "id")
            try container.encodeIfPresent(self.targetDeviceStatus, forKey: .targetDeviceStatus)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 512)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-zA-Z0-9]{24}$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case targetDeviceStatus = "targetDeviceStatus"
        }
    }

    public struct DeregisterDeviceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct Device: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the device.
        public let arn: String?
        /// The timestamp of when the device was created.
        public let createdAt: Date?
        /// The ID of the software set currently installed on the device.
        public let currentSoftwareSetId: String?
        /// The version of the software set currently installed on the device.
        public let currentSoftwareSetVersion: String?
        /// The ID of the software set which the device has been set to.
        public let desiredSoftwareSetId: String?
        /// The ID of the environment the device is associated with.
        public let environmentId: String?
        /// The ID of the device.
        public let id: String?
        /// The Amazon Resource Name (ARN) of the Key Management Service key used to encrypt the device.
        public let kmsKeyArn: String?
        /// The timestamp of the most recent session on the device.
        public let lastConnectedAt: Date?
        /// The timestamp of the most recent check-in of the device.
        public let lastPostureAt: Date?
        /// The model number of the device.
        public let model: String?
        /// The name of the device.
        public let name: String?
        /// The ID of the software set that is pending to be installed on the device.
        public let pendingSoftwareSetId: String?
        /// The version of the software set that is pending to be installed on the device.
        public let pendingSoftwareSetVersion: String?
        /// The hardware serial number of the device.
        public let serialNumber: String?
        /// Describes if the software currently installed on the device is a supported version.
        public let softwareSetComplianceStatus: DeviceSoftwareSetComplianceStatus?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?
        /// Describes if the device has a supported version of software installed.
        public let softwareSetUpdateStatus: SoftwareSetUpdateStatus?
        /// The status of the device.
        public let status: DeviceStatus?
        /// The timestamp of when the device was updated.
        public let updatedAt: Date?

        @inlinable
        public init(arn: String? = nil, createdAt: Date? = nil, currentSoftwareSetId: String? = nil, currentSoftwareSetVersion: String? = nil, desiredSoftwareSetId: String? = nil, environmentId: String? = nil, id: String? = nil, kmsKeyArn: String? = nil, lastConnectedAt: Date? = nil, lastPostureAt: Date? = nil, model: String? = nil, name: String? = nil, pendingSoftwareSetId: String? = nil, pendingSoftwareSetVersion: String? = nil, serialNumber: String? = nil, softwareSetComplianceStatus: DeviceSoftwareSetComplianceStatus? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil, softwareSetUpdateStatus: SoftwareSetUpdateStatus? = nil, status: DeviceStatus? = nil, updatedAt: Date? = nil) {
            self.arn = arn
            self.createdAt = createdAt
            self.currentSoftwareSetId = currentSoftwareSetId
            self.currentSoftwareSetVersion = currentSoftwareSetVersion
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.environmentId = environmentId
            self.id = id
            self.kmsKeyArn = kmsKeyArn
            self.lastConnectedAt = lastConnectedAt
            self.lastPostureAt = lastPostureAt
            self.model = model
            self.name = name
            self.pendingSoftwareSetId = pendingSoftwareSetId
            self.pendingSoftwareSetVersion = pendingSoftwareSetVersion
            self.serialNumber = serialNumber
            self.softwareSetComplianceStatus = softwareSetComplianceStatus
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
            self.softwareSetUpdateStatus = softwareSetUpdateStatus
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createdAt = "createdAt"
            case currentSoftwareSetId = "currentSoftwareSetId"
            case currentSoftwareSetVersion = "currentSoftwareSetVersion"
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case environmentId = "environmentId"
            case id = "id"
            case kmsKeyArn = "kmsKeyArn"
            case lastConnectedAt = "lastConnectedAt"
            case lastPostureAt = "lastPostureAt"
            case model = "model"
            case name = "name"
            case pendingSoftwareSetId = "pendingSoftwareSetId"
            case pendingSoftwareSetVersion = "pendingSoftwareSetVersion"
            case serialNumber = "serialNumber"
            case softwareSetComplianceStatus = "softwareSetComplianceStatus"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
            case softwareSetUpdateStatus = "softwareSetUpdateStatus"
            case status = "status"
            case updatedAt = "updatedAt"
        }
    }

    public struct DeviceSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the device.
        public let arn: String?
        /// The timestamp of when the device was created.
        public let createdAt: Date?
        /// The ID of the software set currently installed on the device.
        public let currentSoftwareSetId: String?
        /// The ID of the software set which the device has been set to.
        public let desiredSoftwareSetId: String?
        /// The ID of the environment the device is associated with.
        public let environmentId: String?
        /// The ID of the device.
        public let id: String?
        /// The timestamp of the most recent session on the device.
        public let lastConnectedAt: Date?
        /// The timestamp of the most recent check-in of the device.
        public let lastPostureAt: Date?
        /// The model number of the device.
        public let model: String?
        /// The name of the device.
        public let name: String?
        /// The ID of the software set that is pending to be installed on the device.
        public let pendingSoftwareSetId: String?
        /// The hardware serial number of the device.
        public let serialNumber: String?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?
        /// The status of the device.
        public let status: DeviceStatus?
        /// The timestamp of when the device was updated.
        public let updatedAt: Date?

        @inlinable
        public init(arn: String? = nil, createdAt: Date? = nil, currentSoftwareSetId: String? = nil, desiredSoftwareSetId: String? = nil, environmentId: String? = nil, id: String? = nil, lastConnectedAt: Date? = nil, lastPostureAt: Date? = nil, model: String? = nil, name: String? = nil, pendingSoftwareSetId: String? = nil, serialNumber: String? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil, status: DeviceStatus? = nil, updatedAt: Date? = nil) {
            self.arn = arn
            self.createdAt = createdAt
            self.currentSoftwareSetId = currentSoftwareSetId
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.environmentId = environmentId
            self.id = id
            self.lastConnectedAt = lastConnectedAt
            self.lastPostureAt = lastPostureAt
            self.model = model
            self.name = name
            self.pendingSoftwareSetId = pendingSoftwareSetId
            self.serialNumber = serialNumber
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createdAt = "createdAt"
            case currentSoftwareSetId = "currentSoftwareSetId"
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case environmentId = "environmentId"
            case id = "id"
            case lastConnectedAt = "lastConnectedAt"
            case lastPostureAt = "lastPostureAt"
            case model = "model"
            case name = "name"
            case pendingSoftwareSetId = "pendingSoftwareSetId"
            case serialNumber = "serialNumber"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
            case status = "status"
            case updatedAt = "updatedAt"
        }
    }

    public struct Environment: AWSDecodableShape {
        /// The activation code to register a device to the environment.
        public let activationCode: String?
        /// The Amazon Resource Name (ARN) of the environment.
        public let arn: String?
        /// The timestamp of when the environment was created.
        public let createdAt: Date?
        /// The ID of the software set to apply.
        public let desiredSoftwareSetId: String?
        /// The Amazon Resource Name (ARN) of the desktop to stream from Amazon WorkSpaces, WorkSpaces Secure Browser, or AppStream 2.0.
        public let desktopArn: String?
        /// The URL for the identity provider login (only for environments that use AppStream 2.0).
        public let desktopEndpoint: String?
        /// The type of streaming desktop for the environment.
        public let desktopType: DesktopType?
        /// The tag keys and optional values for the newly created devices for this environment.
        public let deviceCreationTags: [String: String]?
        /// The ID of the environment.
        public let id: String?
        /// The Amazon Resource Name (ARN) of the Key Management Service key used to encrypt the environment.
        public let kmsKeyArn: String?
        /// A specification for a time window to apply software updates.
        public let maintenanceWindow: MaintenanceWindow?
        /// The name of the environment.
        public let name: String?
        /// The ID of the software set that is pending to be installed.
        public let pendingSoftwareSetId: String?
        /// The version of the software set that is pending to be installed.
        public let pendingSoftwareSetVersion: String?
        /// The number of devices registered to the environment.
        public let registeredDevicesCount: Int?
        /// Describes if the software currently installed on all devices in the environment is a supported version.
        public let softwareSetComplianceStatus: EnvironmentSoftwareSetComplianceStatus?
        /// An option to define which software updates to apply.
        public let softwareSetUpdateMode: SoftwareSetUpdateMode?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?
        /// The timestamp of when the device was updated.
        public let updatedAt: Date?

        @inlinable
        public init(activationCode: String? = nil, arn: String? = nil, createdAt: Date? = nil, desiredSoftwareSetId: String? = nil, desktopArn: String? = nil, desktopEndpoint: String? = nil, desktopType: DesktopType? = nil, deviceCreationTags: [String: String]? = nil, id: String? = nil, kmsKeyArn: String? = nil, maintenanceWindow: MaintenanceWindow? = nil, name: String? = nil, pendingSoftwareSetId: String? = nil, pendingSoftwareSetVersion: String? = nil, registeredDevicesCount: Int? = nil, softwareSetComplianceStatus: EnvironmentSoftwareSetComplianceStatus? = nil, softwareSetUpdateMode: SoftwareSetUpdateMode? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil, updatedAt: Date? = nil) {
            self.activationCode = activationCode
            self.arn = arn
            self.createdAt = createdAt
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.desktopArn = desktopArn
            self.desktopEndpoint = desktopEndpoint
            self.desktopType = desktopType
            self.deviceCreationTags = deviceCreationTags
            self.id = id
            self.kmsKeyArn = kmsKeyArn
            self.maintenanceWindow = maintenanceWindow
            self.name = name
            self.pendingSoftwareSetId = pendingSoftwareSetId
            self.pendingSoftwareSetVersion = pendingSoftwareSetVersion
            self.registeredDevicesCount = registeredDevicesCount
            self.softwareSetComplianceStatus = softwareSetComplianceStatus
            self.softwareSetUpdateMode = softwareSetUpdateMode
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case activationCode = "activationCode"
            case arn = "arn"
            case createdAt = "createdAt"
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case desktopArn = "desktopArn"
            case desktopEndpoint = "desktopEndpoint"
            case desktopType = "desktopType"
            case deviceCreationTags = "deviceCreationTags"
            case id = "id"
            case kmsKeyArn = "kmsKeyArn"
            case maintenanceWindow = "maintenanceWindow"
            case name = "name"
            case pendingSoftwareSetId = "pendingSoftwareSetId"
            case pendingSoftwareSetVersion = "pendingSoftwareSetVersion"
            case registeredDevicesCount = "registeredDevicesCount"
            case softwareSetComplianceStatus = "softwareSetComplianceStatus"
            case softwareSetUpdateMode = "softwareSetUpdateMode"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
            case updatedAt = "updatedAt"
        }
    }

    public struct EnvironmentSummary: AWSDecodableShape {
        /// The activation code to register a device to the environment.
        public let activationCode: String?
        /// The Amazon Resource Name (ARN) of the environment.
        public let arn: String?
        /// The timestamp of when the environment was created.
        public let createdAt: Date?
        /// The ID of the software set to apply.
        public let desiredSoftwareSetId: String?
        /// The Amazon Resource Name (ARN) of the desktop to stream from Amazon WorkSpaces, WorkSpaces Secure Browser, or AppStream 2.0.
        public let desktopArn: String?
        /// The URL for the identity provider login (only for environments that use AppStream 2.0).
        public let desktopEndpoint: String?
        /// The type of streaming desktop for the environment.
        public let desktopType: DesktopType?
        /// The ID of the environment.
        public let id: String?
        /// A specification for a time window to apply software updates.
        public let maintenanceWindow: MaintenanceWindow?
        /// The name of the environment.
        public let name: String?
        /// The ID of the software set that is pending to be installed.
        public let pendingSoftwareSetId: String?
        /// An option to define which software updates to apply.
        public let softwareSetUpdateMode: SoftwareSetUpdateMode?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?
        /// The timestamp of when the device was updated.
        public let updatedAt: Date?

        @inlinable
        public init(activationCode: String? = nil, arn: String? = nil, createdAt: Date? = nil, desiredSoftwareSetId: String? = nil, desktopArn: String? = nil, desktopEndpoint: String? = nil, desktopType: DesktopType? = nil, id: String? = nil, maintenanceWindow: MaintenanceWindow? = nil, name: String? = nil, pendingSoftwareSetId: String? = nil, softwareSetUpdateMode: SoftwareSetUpdateMode? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil, updatedAt: Date? = nil) {
            self.activationCode = activationCode
            self.arn = arn
            self.createdAt = createdAt
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.desktopArn = desktopArn
            self.desktopEndpoint = desktopEndpoint
            self.desktopType = desktopType
            self.id = id
            self.maintenanceWindow = maintenanceWindow
            self.name = name
            self.pendingSoftwareSetId = pendingSoftwareSetId
            self.softwareSetUpdateMode = softwareSetUpdateMode
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case activationCode = "activationCode"
            case arn = "arn"
            case createdAt = "createdAt"
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case desktopArn = "desktopArn"
            case desktopEndpoint = "desktopEndpoint"
            case desktopType = "desktopType"
            case id = "id"
            case maintenanceWindow = "maintenanceWindow"
            case name = "name"
            case pendingSoftwareSetId = "pendingSoftwareSetId"
            case softwareSetUpdateMode = "softwareSetUpdateMode"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
            case updatedAt = "updatedAt"
        }
    }

    public struct GetDeviceRequest: AWSEncodableShape {
        /// The ID of the device for which to return information.
        public let id: String

        @inlinable
        public init(id: String) {
            self.id = id
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.id, key: "id")
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-zA-Z0-9]{24}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetDeviceResponse: AWSDecodableShape {
        /// Describes an device.
        public let device: Device?

        @inlinable
        public init(device: Device? = nil) {
            self.device = device
        }

        private enum CodingKeys: String, CodingKey {
            case device = "device"
        }
    }

    public struct GetEnvironmentRequest: AWSEncodableShape {
        /// The ID of the environment for which to return information.
        public let id: String

        @inlinable
        public init(id: String) {
            self.id = id
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.id, key: "id")
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-z0-9]{9}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetEnvironmentResponse: AWSDecodableShape {
        /// Describes an environment.
        public let environment: Environment?

        @inlinable
        public init(environment: Environment? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "environment"
        }
    }

    public struct GetSoftwareSetRequest: AWSEncodableShape {
        /// The ID of the software set for which to return information.
        public let id: String

        @inlinable
        public init(id: String) {
            self.id = id
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.id, key: "id")
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, pattern: "^[0-9]{1,9}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetSoftwareSetResponse: AWSDecodableShape {
        /// Describes a software set.
        public let softwareSet: SoftwareSet?

        @inlinable
        public init(softwareSet: SoftwareSet? = nil) {
            self.softwareSet = softwareSet
        }

        private enum CodingKeys: String, CodingKey {
            case softwareSet = "softwareSet"
        }
    }

    public struct InternalServerException: AWSErrorShape {
        public let message: String?
        /// The number of seconds to wait before retrying the next request.
        public let retryAfterSeconds: Int?

        @inlinable
        public init(message: String? = nil, retryAfterSeconds: Int? = nil) {
            self.message = message
            self.retryAfterSeconds = retryAfterSeconds
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decodeIfPresent(String.self, forKey: .message)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
        }
    }

    public struct ListDevicesRequest: AWSEncodableShape {
        /// The maximum number of results that are returned per call. You can use nextToken to obtain further pages of results. This is only an upper limit. The actual number of results returned per call might be fewer than the specified maximum.
        public let maxResults: Int?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\S*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListDevicesResponse: AWSDecodableShape {
        /// Describes devices.
        public let devices: [DeviceSummary]?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(devices: [DeviceSummary]? = nil, nextToken: String? = nil) {
            self.devices = devices
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case devices = "devices"
            case nextToken = "nextToken"
        }
    }

    public struct ListEnvironmentsRequest: AWSEncodableShape {
        /// The maximum number of results that are returned per call. You can use nextToken to obtain further pages of results. This is only an upper limit. The actual number of results returned per call might be fewer than the specified maximum.
        public let maxResults: Int?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\S*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListEnvironmentsResponse: AWSDecodableShape {
        /// Describes environments.
        public let environments: [EnvironmentSummary]?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(environments: [EnvironmentSummary]? = nil, nextToken: String? = nil) {
            self.environments = environments
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case environments = "environments"
            case nextToken = "nextToken"
        }
    }

    public struct ListSoftwareSetsRequest: AWSEncodableShape {
        /// The maximum number of results that are returned per call. You can use nextToken to obtain further pages of results. This is only an upper limit. The actual number of results returned per call might be fewer than the specified maximum.
        public let maxResults: Int?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\S*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSoftwareSetsResponse: AWSDecodableShape {
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?
        /// Describes software sets.
        public let softwareSets: [SoftwareSetSummary]?

        @inlinable
        public init(nextToken: String? = nil, softwareSets: [SoftwareSetSummary]? = nil) {
            self.nextToken = nextToken
            self.softwareSets = softwareSets
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case softwareSets = "softwareSets"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource for which you want to retrieve tags.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// A map of the key-value pairs for the tag or tags assigned to the specified resource.
        public let tags: [String: String]?

        @inlinable
        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct MaintenanceWindow: AWSEncodableShape & AWSDecodableShape {
        /// The option to set the maintenance window during the device local time or Universal Coordinated Time (UTC).
        public let applyTimeOf: ApplyTimeOf?
        /// The days of the week during which the maintenance window is open.
        public let daysOfTheWeek: [DayOfWeek]?
        /// The hour for the maintenance window end (00-23).
        public let endTimeHour: Int?
        /// The minutes for the maintenance window end (00-59).
        public let endTimeMinute: Int?
        /// The hour for the maintenance window start (00-23).
        public let startTimeHour: Int?
        /// The minutes past the hour for the maintenance window start (00-59).
        public let startTimeMinute: Int?
        /// An option to select the default or custom maintenance window.
        public let type: MaintenanceWindowType

        @inlinable
        public init(applyTimeOf: ApplyTimeOf? = nil, daysOfTheWeek: [DayOfWeek]? = nil, endTimeHour: Int? = nil, endTimeMinute: Int? = nil, startTimeHour: Int? = nil, startTimeMinute: Int? = nil, type: MaintenanceWindowType) {
            self.applyTimeOf = applyTimeOf
            self.daysOfTheWeek = daysOfTheWeek
            self.endTimeHour = endTimeHour
            self.endTimeMinute = endTimeMinute
            self.startTimeHour = startTimeHour
            self.startTimeMinute = startTimeMinute
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.daysOfTheWeek, name: "daysOfTheWeek", parent: name, max: 7)
            try self.validate(self.daysOfTheWeek, name: "daysOfTheWeek", parent: name, min: 1)
            try self.validate(self.endTimeHour, name: "endTimeHour", parent: name, max: 23)
            try self.validate(self.endTimeHour, name: "endTimeHour", parent: name, min: 0)
            try self.validate(self.endTimeMinute, name: "endTimeMinute", parent: name, max: 59)
            try self.validate(self.endTimeMinute, name: "endTimeMinute", parent: name, min: 0)
            try self.validate(self.startTimeHour, name: "startTimeHour", parent: name, max: 23)
            try self.validate(self.startTimeHour, name: "startTimeHour", parent: name, min: 0)
            try self.validate(self.startTimeMinute, name: "startTimeMinute", parent: name, max: 59)
            try self.validate(self.startTimeMinute, name: "startTimeMinute", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case applyTimeOf = "applyTimeOf"
            case daysOfTheWeek = "daysOfTheWeek"
            case endTimeHour = "endTimeHour"
            case endTimeMinute = "endTimeMinute"
            case startTimeHour = "startTimeHour"
            case startTimeMinute = "startTimeMinute"
            case type = "type"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        public let message: String?
        /// The ID of the resource associated with the request.
        public let resourceId: String?
        /// The type of the resource associated with the request.
        public let resourceType: String?

        @inlinable
        public init(message: String? = nil, resourceId: String? = nil, resourceType: String? = nil) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct ServiceQuotaExceededException: AWSErrorShape {
        public let message: String?
        /// The code for the quota in Service Quotas.
        public let quotaCode: String?
        /// The ID of the resource that exceeds the service quota.
        public let resourceId: String?
        /// The type of the resource that exceeds the service quota.
        public let resourceType: String?
        /// The code for the service in Service Quotas.
        public let serviceCode: String?

        @inlinable
        public init(message: String? = nil, quotaCode: String? = nil, resourceId: String? = nil, resourceType: String? = nil, serviceCode: String? = nil) {
            self.message = message
            self.quotaCode = quotaCode
            self.resourceId = resourceId
            self.resourceType = resourceType
            self.serviceCode = serviceCode
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
            case serviceCode = "serviceCode"
        }
    }

    public struct Software: AWSDecodableShape {
        /// The name of the software component.
        public let name: String?
        /// The version of the software component.
        public let version: String?

        @inlinable
        public init(name: String? = nil, version: String? = nil) {
            self.name = name
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case name = "name"
            case version = "version"
        }
    }

    public struct SoftwareSet: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the software set.
        public let arn: String?
        /// The ID of the software set.
        public let id: String?
        /// The timestamp of when the software set was released.
        public let releasedAt: Date?
        /// A list of the software components in the software set.
        public let software: [Software]?
        /// The timestamp of the end of support for the software set.
        public let supportedUntil: Date?
        /// An option to define if the software set has been validated.
        public let validationStatus: SoftwareSetValidationStatus?
        /// The version of the software set.
        public let version: String?

        @inlinable
        public init(arn: String? = nil, id: String? = nil, releasedAt: Date? = nil, software: [Software]? = nil, supportedUntil: Date? = nil, validationStatus: SoftwareSetValidationStatus? = nil, version: String? = nil) {
            self.arn = arn
            self.id = id
            self.releasedAt = releasedAt
            self.software = software
            self.supportedUntil = supportedUntil
            self.validationStatus = validationStatus
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case id = "id"
            case releasedAt = "releasedAt"
            case software = "software"
            case supportedUntil = "supportedUntil"
            case validationStatus = "validationStatus"
            case version = "version"
        }
    }

    public struct SoftwareSetSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the software set.
        public let arn: String?
        /// The ID of the software set.
        public let id: String?
        /// The timestamp of when the software set was released.
        public let releasedAt: Date?
        /// The timestamp of the end of support for the software set.
        public let supportedUntil: Date?
        /// An option to define if the software set has been validated.
        public let validationStatus: SoftwareSetValidationStatus?
        /// The version of the software set.
        public let version: String?

        @inlinable
        public init(arn: String? = nil, id: String? = nil, releasedAt: Date? = nil, supportedUntil: Date? = nil, validationStatus: SoftwareSetValidationStatus? = nil, version: String? = nil) {
            self.arn = arn
            self.id = id
            self.releasedAt = releasedAt
            self.supportedUntil = supportedUntil
            self.validationStatus = validationStatus
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case id = "id"
            case releasedAt = "releasedAt"
            case supportedUntil = "supportedUntil"
            case validationStatus = "validationStatus"
            case version = "version"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource that you want to tag.
        public let resourceArn: String
        /// A map of the key-value pairs of the tag or tags to assign to the resource.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        public let message: String?
        /// The code for the quota in Service Quotas.
        public let quotaCode: String?
        /// The number of seconds to wait before retrying the next request.
        public let retryAfterSeconds: Int?
        /// The code for the service in Service Quotas.
        public let serviceCode: String?

        @inlinable
        public init(message: String? = nil, quotaCode: String? = nil, retryAfterSeconds: Int? = nil, serviceCode: String? = nil) {
            self.message = message
            self.quotaCode = quotaCode
            self.retryAfterSeconds = retryAfterSeconds
            self.serviceCode = serviceCode
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decodeIfPresent(String.self, forKey: .message)
            self.quotaCode = try container.decodeIfPresent(String.self, forKey: .quotaCode)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
            self.serviceCode = try container.decodeIfPresent(String.self, forKey: .serviceCode)
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case serviceCode = "serviceCode"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource that you want to untag.
        public let resourceArn: String
        /// The keys of the key-value pairs for the tag or tags you want to remove from the specified resource.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateDeviceRequest: AWSEncodableShape {
        /// The ID of the software set to apply.
        public let desiredSoftwareSetId: String?
        /// The ID of the device to update.
        public let id: String
        /// The name of the device to update.
        public let name: String?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?

        @inlinable
        public init(desiredSoftwareSetId: String? = nil, id: String, name: String? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil) {
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.id = id
            self.name = name
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.desiredSoftwareSetId, forKey: .desiredSoftwareSetId)
            request.encodePath(self.id, key: "id")
            try container.encodeIfPresent(self.name, forKey: .name)
            try container.encodeIfPresent(self.softwareSetUpdateSchedule, forKey: .softwareSetUpdateSchedule)
        }

        public func validate(name: String) throws {
            try self.validate(self.desiredSoftwareSetId, name: "desiredSoftwareSetId", parent: name, pattern: "^[0-9]{1,9}$")
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-zA-Z0-9]{24}$")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^$|^[0-9\\p{IsAlphabetic}+:,.@'\" -]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case name = "name"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
        }
    }

    public struct UpdateDeviceResponse: AWSDecodableShape {
        /// Describes a device.
        public let device: DeviceSummary?

        @inlinable
        public init(device: DeviceSummary? = nil) {
            self.device = device
        }

        private enum CodingKeys: String, CodingKey {
            case device = "device"
        }
    }

    public struct UpdateEnvironmentRequest: AWSEncodableShape {
        /// The ID of the software set to apply.
        public let desiredSoftwareSetId: String?
        /// The Amazon Resource Name (ARN) of the desktop to stream from Amazon WorkSpaces, WorkSpaces Secure Browser, or AppStream 2.0.
        public let desktopArn: String?
        /// The URL for the identity provider login (only for environments that use AppStream 2.0).
        public let desktopEndpoint: String?
        /// A map of the key-value pairs of the tag or tags to assign to the newly created devices for this environment.
        public let deviceCreationTags: [String: String]?
        /// The ID of the environment to update.
        public let id: String
        /// A specification for a time window to apply software updates.
        public let maintenanceWindow: MaintenanceWindow?
        /// The name of the environment to update.
        public let name: String?
        /// An option to define which software updates to apply.
        public let softwareSetUpdateMode: SoftwareSetUpdateMode?
        /// An option to define if software updates should be applied within a maintenance window.
        public let softwareSetUpdateSchedule: SoftwareSetUpdateSchedule?

        @inlinable
        public init(desiredSoftwareSetId: String? = nil, desktopArn: String? = nil, desktopEndpoint: String? = nil, deviceCreationTags: [String: String]? = nil, id: String, maintenanceWindow: MaintenanceWindow? = nil, name: String? = nil, softwareSetUpdateMode: SoftwareSetUpdateMode? = nil, softwareSetUpdateSchedule: SoftwareSetUpdateSchedule? = nil) {
            self.desiredSoftwareSetId = desiredSoftwareSetId
            self.desktopArn = desktopArn
            self.desktopEndpoint = desktopEndpoint
            self.deviceCreationTags = deviceCreationTags
            self.id = id
            self.maintenanceWindow = maintenanceWindow
            self.name = name
            self.softwareSetUpdateMode = softwareSetUpdateMode
            self.softwareSetUpdateSchedule = softwareSetUpdateSchedule
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.desiredSoftwareSetId, forKey: .desiredSoftwareSetId)
            try container.encodeIfPresent(self.desktopArn, forKey: .desktopArn)
            try container.encodeIfPresent(self.desktopEndpoint, forKey: .desktopEndpoint)
            try container.encodeIfPresent(self.deviceCreationTags, forKey: .deviceCreationTags)
            request.encodePath(self.id, key: "id")
            try container.encodeIfPresent(self.maintenanceWindow, forKey: .maintenanceWindow)
            try container.encodeIfPresent(self.name, forKey: .name)
            try container.encodeIfPresent(self.softwareSetUpdateMode, forKey: .softwareSetUpdateMode)
            try container.encodeIfPresent(self.softwareSetUpdateSchedule, forKey: .softwareSetUpdateSchedule)
        }

        public func validate(name: String) throws {
            try self.validate(self.desiredSoftwareSetId, name: "desiredSoftwareSetId", parent: name, pattern: "^[0-9]{0,9}$")
            try self.validate(self.desktopArn, name: "desktopArn", parent: name, max: 2048)
            try self.validate(self.desktopArn, name: "desktopArn", parent: name, min: 20)
            try self.validate(self.desktopArn, name: "desktopArn", parent: name, pattern: "^arn:[\\w+=\\/,.@-]+:[a-zA-Z0-9\\-]+:[a-zA-Z0-9\\-]*:[0-9]{0,12}:[a-zA-Z0-9\\-\\/\\._]+$")
            try self.validate(self.desktopEndpoint, name: "desktopEndpoint", parent: name, max: 1024)
            try self.validate(self.desktopEndpoint, name: "desktopEndpoint", parent: name, min: 1)
            try self.validate(self.desktopEndpoint, name: "desktopEndpoint", parent: name, pattern: "^(https:\\/\\/)[a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,32}(:[0-9]{1,5})?(\\/.*)?$")
            try self.deviceCreationTags?.forEach {
                try validate($0.key, name: "deviceCreationTags.key", parent: name, max: 128)
                try validate($0.key, name: "deviceCreationTags.key", parent: name, min: 1)
                try validate($0.key, name: "deviceCreationTags.key", parent: name, pattern: "^(?!aws:)[A-Za-z0-9 _=@:.+-/]+$")
                try validate($0.value, name: "deviceCreationTags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "deviceCreationTags[\"\($0.key)\"]", parent: name, pattern: "^[A-Za-z0-9 _=@:.+-/]+$")
            }
            try self.validate(self.deviceCreationTags, name: "deviceCreationTags", parent: name, max: 50)
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-z0-9]{9}$")
            try self.maintenanceWindow?.validate(name: "\(name).maintenanceWindow")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^$|^[0-9\\p{IsAlphabetic}+:,.@'\" -][0-9\\p{IsAlphabetic}+=:,.@'\" -]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case desiredSoftwareSetId = "desiredSoftwareSetId"
            case desktopArn = "desktopArn"
            case desktopEndpoint = "desktopEndpoint"
            case deviceCreationTags = "deviceCreationTags"
            case maintenanceWindow = "maintenanceWindow"
            case name = "name"
            case softwareSetUpdateMode = "softwareSetUpdateMode"
            case softwareSetUpdateSchedule = "softwareSetUpdateSchedule"
        }
    }

    public struct UpdateEnvironmentResponse: AWSDecodableShape {
        /// Describes an environment.
        public let environment: EnvironmentSummary?

        @inlinable
        public init(environment: EnvironmentSummary? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "environment"
        }
    }

    public struct UpdateSoftwareSetRequest: AWSEncodableShape {
        /// The ID of the software set to update.
        public let id: String
        /// An option to define if the software set has been validated.
        public let validationStatus: SoftwareSetValidationStatus

        @inlinable
        public init(id: String, validationStatus: SoftwareSetValidationStatus) {
            self.id = id
            self.validationStatus = validationStatus
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.id, key: "id")
            try container.encode(self.validationStatus, forKey: .validationStatus)
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, pattern: "^[0-9]{1,9}$")
        }

        private enum CodingKeys: String, CodingKey {
            case validationStatus = "validationStatus"
        }
    }

    public struct UpdateSoftwareSetResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ValidationException: AWSErrorShape {
        /// A list of fields that didn't validate.
        public let fieldList: [ValidationExceptionField]?
        public let message: String?
        /// The reason for the exception.
        public let reason: ValidationExceptionReason?

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String? = nil, reason: ValidationExceptionReason? = nil) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// A message that describes the reason for the exception.
        public let message: String
        /// The name of the exception.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }
}

// MARK: - Errors

/// Error enum for WorkSpacesThinClient
public struct WorkSpacesThinClientErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize WorkSpacesThinClient
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The requested operation would cause a conflict with the current state of a service resource associated with the request. Resolve the conflict before retrying this request.
    public static var conflictException: Self { .init(.conflictException) }
    /// The server encountered an internal error and is unable to complete the request.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The resource specified in the request was not found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Your request exceeds a service quota.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The input fails to satisfy the specified constraints.
    public static var validationException: Self { .init(.validationException) }
}

extension WorkSpacesThinClientErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ConflictException": WorkSpacesThinClient.ConflictException.self,
        "InternalServerException": WorkSpacesThinClient.InternalServerException.self,
        "ResourceNotFoundException": WorkSpacesThinClient.ResourceNotFoundException.self,
        "ServiceQuotaExceededException": WorkSpacesThinClient.ServiceQuotaExceededException.self,
        "ThrottlingException": WorkSpacesThinClient.ThrottlingException.self,
        "ValidationException": WorkSpacesThinClient.ValidationException.self
    ]
}

extension WorkSpacesThinClientErrorType: Equatable {
    public static func == (lhs: WorkSpacesThinClientErrorType, rhs: WorkSpacesThinClientErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension WorkSpacesThinClientErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
